package com.ruoyi.project.order.service.date;

import cn.hutool.core.date.DateUnit;

import java.lang.management.ManagementFactory;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateUtil {

	public static String YYYY = "yyyy";

	public static String YYYY_MM = "yyyy-MM";

	public static String YYYY_MM_DD = "yyyy-MM-dd";

	public static String YYYYMMDD = "yyyyMMdd";

	public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

	public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

	private static String[] parsePatterns = {
		"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
		"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
		"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM",
		"yyyyMMdd"
	};

	/**
	 * -获取系统嘀嗒数
	 * ticks是从0000年1月1日0时开始到当前的毫秒数
	 * @return Long类型 ticks
	 */
	public static long getTicks() {
		long milli = System.currentTimeMillis() + 8 * 3600 * 1000;
		long ticks = (milli * 10000) + 621355968000000000L;
		return ticks;
	}

	/**
	 *  ticks是从0000年1月1日0时开始到当前的毫秒数
	 * @return
	 */
	public static long getTicks2() {
		String dateStr1 = "0000-01-01 00:00:00";
		Date date1 = cn.hutool.core.date.DateUtil.parse(dateStr1);
		Date date2 = new Date();
		long ticks = cn.hutool.core.date.DateUtil.between(date1, date2, DateUnit.MS);
		return ticks;
	}


	/**
	 * -时间戳转换成日期格式字符串
	 *
	 * @param seconds 精确到分钟的字符串
	 * @param format
	 * @return
	 */
	public static String timeStamp2Date(String seconds, String format) {
		if (seconds == null || seconds.isEmpty() || seconds.equals("null")) {
			return "";
		}
		if (format == null || format.isEmpty()) {
			format = format;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(new Date(Long.valueOf(seconds + "000")));
	}

	/**
	 * -日期格式字符串转换成时间戳
	 *
	 * @param date_str 字符串日期
	 * @param format   如：yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static String date2TimeStamp(String date_str, String format) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(format);
			return String.valueOf(sdf.parse(date_str).getTime() / 1000);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * -取得当前时间戳（精确到秒）
	 *
	 * @return
	 */
	public static String timeStamp() {
		long time = System.currentTimeMillis();
		String t = String.valueOf(time / 1000);
		return t;
	}

	/**
	 * @return yyyyMMddHHmmss
	 */
	public static String getCurrentTime() {
		String currentDate = "";
		Date date = new Date();
		SimpleDateFormat smpdf = new SimpleDateFormat("yyyyMMddHHmmss");
		currentDate = smpdf.format(date);
		return currentDate;
	}
	/**
	 * @return yyyyMMddHHmmss
	 */
	public static String getCurrentTime(String dfm) {
		String currentDate = "";
		Date date = new Date();
		SimpleDateFormat smpdf = new SimpleDateFormat(dfm);
		currentDate = smpdf.format(date);
		return currentDate;
	}

	/**
	 * @return dfm 格式的字符串
	 */
	public static String getDateStr(String date, String dfm) {
		if(null==date || date.isEmpty()){
			return date;
		}
		String currentDate = "";
		SimpleDateFormat smpdf = new SimpleDateFormat(dfm);
		currentDate = smpdf.format(date);
		return currentDate;
	}

	/**
	 * @return dfm 格式的字符串
	 */
	/**
	 *
	 * 将一个日期字符换成指定格式的日期字符串
	 * @param date 日期类型字符串
	 * @param curr_dfm date字符串日期格式 默认 yyyy-MM-dd HH:mm:ss
	 * @param targ_dfm 目标格式
	 * @return 目标格式的日期字符串
	 */
	public static String getDateStr(String date, String curr_dfm, String targ_dfm) {
		if(null==date || date.isEmpty()){
			return date;
		}
		if(null==curr_dfm || curr_dfm.isEmpty()){
			curr_dfm="yyyy-MM-dd HH:mm:ss";
		}
		SimpleDateFormat smpdf_start = new SimpleDateFormat(curr_dfm);
		Date date_start = new Date();
		try {
			date_start = smpdf_start.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
			return date;
		}
		String currentDate = "";
		SimpleDateFormat smpdf = new SimpleDateFormat(targ_dfm);
		currentDate = smpdf.format(date_start);
		return currentDate;
	}

	/**
	 * @return yyyy-MM-dd HH:mm:ss
	 */
	public static String getEasyTime() {
		String currentDate = "";
		Date date = new Date();
		SimpleDateFormat smpdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		currentDate = smpdf.format(date);
		return currentDate;
	}

	/**
	 * @return yyyyMMdd
	 */
	public static String getCurrentDate() {
		String currentDate = "";
		Date date = new Date();
		SimpleDateFormat smpdf = new SimpleDateFormat("yyyyMMdd");
		currentDate = smpdf.format(date);
		return currentDate;
	}

	/**
	 * @retur yyyy-MM-dd
	 */
	public static String getEasyDate() {
		String currentDate = "";
		Date date = new Date();
		SimpleDateFormat smpdf = new SimpleDateFormat("yyyy-MM-dd");
		currentDate = smpdf.format(date);
		return currentDate;
	}

	/**
	 * 判断日期格式是否正确
	 * @retur Boolean
	 */
	public static String isAppointSmart(String dateStr , String smart) {
		String currentDate = "";
		Date date = new Date(dateStr);
		SimpleDateFormat smpdf = new SimpleDateFormat(smart);
		currentDate = smpdf.format(date);
		return currentDate;
	}

	/**
	 * @param str 指定日期格式
	 * @return 指定日期格式的字符串
	 */
	public static String getDateTime(Date date, String str) {
		String currentDate = "";
		SimpleDateFormat smpdf = new SimpleDateFormat(str);
		currentDate = smpdf.format(date);
		return currentDate;
	}

	/**
	 * @param date 指定日期(日期类型）
	 * @return 指定日期格式的字符串
	 */
	public static String getDateTime(Date date) {
		String currentDate = "";
		SimpleDateFormat smpdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		currentDate = smpdf.format(date);
		return currentDate;
	}

	/**
	 * @param str 指定日期格式
	 * @return 指定日期格式的字符串
	 */
	public static String getDateTime(String str) {
		String currentDate = "";
		Date date = new Date();
		SimpleDateFormat smpdf = new SimpleDateFormat(str);
		currentDate = smpdf.format(date);
		return currentDate;
	}

	/**
	 * 说明 ：计算一个与指定日期 相差指定天数 的 日期字符串
	 *
	 * @param dateStr 日期类型的字符串 如：20180228
	 * @param days    需要相隔天数 如：1
	 * @return Str 指定日期的字符串 如：20180501
	 */
	public static String getAppointDate(String dateStr, int days) {
		String appointDate = "";
		// 时间表示格式可以改变，yyyyMMdd需要写例如20160523这种形式的时间
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		// String datestr = "20180228";
		// 将字符串的日期转为Date类型，ParsePosition(0)表示从第一个字符开始解析
		Date date = sdf.parse(dateStr, new ParsePosition(0));
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		// add方法中的第二个参数n中，正数表示该日期后n天，负数表示该日期的前n天
		calendar.add(Calendar.DATE, days);
		Date date1 = calendar.getTime();
		appointDate = sdf.format(date1);
		return appointDate;
	}
	/**
	 * 说明 ：计算一个与指定日期 相差指定天数 的 日期字符串
	 *
	 * @param dateStr 日期类型的字符串 如：20180228
	 * @param days    需要相隔天数 如：1
	 * @return Str 指定日期的字符串 如：20180501
	 */
	public static String getAppointDate(String dateStr, int days, String sfmt) {
		String appointDate = "";
		// 时间表示格式可以改变，yyyyMMdd需要写例如20160523这种形式的时间
		SimpleDateFormat sdf = null;
		if(dateStr==null || "".equals(dateStr)){
			return dateStr;
		}
		if(sfmt!=null) {
			sdf = new SimpleDateFormat(sfmt);
		}else{
			sdf = new SimpleDateFormat("yyyyMMdd");
		}
		// String datestr = "20180228";
		// 将字符串的日期转为Date类型，ParsePosition(0)表示从第一个字符开始解析
		Date date = sdf.parse(dateStr, new ParsePosition(0));
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		// add方法中的第二个参数n中，正数表示该日期后n天，负数表示该日期的前n天
		calendar.add(Calendar.DATE, days);
		Date date1 = calendar.getTime();
		appointDate = sdf.format(date1);
		return appointDate;
	}

	/**
	 * 说明 ：计算一个与指定日期 相差指定分钟数 的 日期字符串
	 *
	 * @param dateStr 日期类型的字符串 如：2018/02/28 10:45:25
	 * @param mins    需要相隔分钟数 如：1
	 * @return Str 指定日期的字符串 如：2018/02/28 10:46:25
	 */
	public static String getAppointTimeByMinute(String dateStr, int mins) {
		String appointTime = "";
		// 时间表示格式可以改变，yyyyMMdd需要写例如20160523这种形式的时间
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		// 将字符串的日期转为Date类型，ParsePosition(0)表示从第一个字符开始解析
		Date date = sdf.parse(dateStr, new ParsePosition(0));
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		// add方法中的第二个参数n中，正数表示该日期后分钟，负数表示该日期的前n分钟
		calendar.add(Calendar.MINUTE, mins);
		Date dateRes = calendar.getTime();
		appointTime = sdf.format(dateRes);
		return appointTime;
	}

	/**
	 * 说明 ：计算一个与指定日期 相差指定分钟数 的 日期字符串
	 *
	 * @param dateFormat 日期格式的字符串 如：yyyy-MM-dd HH:mm:ss
	 * @param dateStr    日期类型的字符串 如：2018/02/28 10:45:25
	 * @param mins       需要相隔分钟数 如：1
	 * @return Str 指定日期的字符串 如：2018/02/28 10:46:25
	 */
	public static String getAppointTimeByMinute(String dateFormat, String dateStr, int mins) {
		String appointTime = "";
		// 时间表示格式可以改变，yyyyMMdd需要写例如20160523这种形式的时间
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		// 将字符串的日期转为Date类型，ParsePosition(0)表示从第一个字符开始解析
		Date date = sdf.parse(dateStr, new ParsePosition(0));
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		// add方法中的第二个参数n中，正数表示该日期后分钟，负数表示该日期的前n分钟
		calendar.add(Calendar.MINUTE, mins);
		Date dateRes = calendar.getTime();
		appointTime = sdf.format(dateRes);
		return appointTime;
	}

	/**
	 * 说明 ：计算一个与指定日期 相差指定秒数 的 日期字符串
	 *
	 * @param dateStr 日期类型的字符串 如：2018/02/28 10:45:25
	 * @param seconds 需要相隔秒数 如：1
	 * @return Str 指定日期的字符串 如：2018/02/28 10:46:25
	 */
	public static String getAppointTimeBySecound(String dateStr, int seconds) {
		String appointTime = "";
		// 时间表示格式可以改变，yyyyMMdd需要写例如20160523这种形式的时间
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		// 将字符串的日期转为Date类型，ParsePosition(0)表示从第一个字符开始解析
		Date date = sdf.parse(dateStr, new ParsePosition(0));
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		// add方法中的第二个参数n中，正数表示该日期后分钟，负数表示该日期的前n分钟
		calendar.add(Calendar.SECOND, seconds);
		Date dateRes = calendar.getTime();
		appointTime = sdf.format(dateRes);
		return appointTime;
	}

	/**
	 * 通过时间毫秒数判断两个时间间隔 相差天数
	 *
	 * @param startDateStr 日期类型字符串 小日期
	 * @param endDateStr   日期类型字符串 大日期
	 * @param smt          日期格式
	 * @return int d1-d0 相差天数
	 */
	public static int differentDaysByMillisecond(String startDateStr, String endDateStr, String smt) {
		SimpleDateFormat format = new SimpleDateFormat(smt);

		Date endDate = null;
		Date startDate = null;
		try {
			endDate = format.parse(endDateStr);
			startDate = format.parse(startDateStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}

		int days = (int) ((endDate.getTime() - startDate.getTime()) / (1000 * 3600 * 24));
		return days;
	}

	/**
	 * 通过时间毫秒数判断两个时间间隔 相差分钟数
	 *
	 * @param startDateStr 日期类型字符串 小日期
	 * @param endDateStr   日期类型字符串 大日期
	 * @param smt          日期格式
	 * @return int d1-d0 相差分钟数
	 */
	public static Long differentMinutesByMillisecond(String startDateStr, String endDateStr, String smt) {
		SimpleDateFormat format = new SimpleDateFormat(smt);

		Date endDate = null;
		Date startDate = null;
		try {
			endDate = format.parse(endDateStr);
			startDate = format.parse(startDateStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}

		Long minutes = (Long) ((endDate.getTime() - startDate.getTime()) / (1000 * 60));
		return minutes;
	}

	/**
	 * 获取服务器启动时间
	 */
	public static Date getServerStartDate() {
		long time = ManagementFactory.getRuntimeMXBean().getStartTime();
		return new Date(time);
	}

	/**
	 * 计算两个时间差
	 *
	 * @param startDate
	 * @param endDate
	 * @return 两个日期之间相差的毫秒数
	 */
	public static String getDatePoor(Date startDate, Date endDate) {
		long nd = 1000 * 24 * 60 * 60;
		long nh = 1000 * 60 * 60;
		long nm = 1000 * 60;
		// long ns = 1000;
		// 获得两个时间的毫秒时间差异
		long diff = endDate.getTime() - startDate.getTime();
		// 计算差多少天
		long day = diff / nd;
		// 计算差多少小时
		long hour = diff % nd / nh;
		// 计算差多少分钟
		long min = diff % nd % nh / nm;
		// 计算差多少秒//输出结果
		// long sec = diff % nd % nh % nm / ns;
		return day + "天" + hour + "小时" + min + "分钟";
	}

	/**
	 * 计算两个时间差
	 *
	 * @param startDate
	 * @param endDate
	 * @return 两个日期之间相差的天数
	 */
	public static Long getDatePoorAsDays(Date startDate, Date endDate) {
		long nd = 1000 * 24 * 60 * 60;
		long nh = 1000 * 60 * 60;
		long nm = 1000 * 60;
		// long ns = 1000;
		// 获得两个时间的毫秒时间差异
		long diff = endDate.getTime() - startDate.getTime();
		// 计算差多少天
		long days = diff / nd;
		// 计算差多少小时
		long hour = diff % nd / nh;
		// 计算差多少分钟
		long min = diff % nd % nh / nm;
		// 计算差多少秒//输出结果
		// long sec = diff % nd % nh % nm / ns;
		return days;
	}
	/**
	 * 计算两个时间差
	 * endDate - startDate
	 * @param startDate
	 * @param endDate
	 * @return 两个日期之间相差的分钟数
	 */
	public static Long getDatePoorAsMins(Date startDate, Date endDate) {
		long nd = 1000 * 24 * 60 * 60;
		long nh = 1000 * 60 * 60;
		long nm = 1000 * 60;
		// long ns = 1000;
		// 获得两个时间的毫秒时间差异
		long diff = endDate.getTime() - startDate.getTime();
		// 计算差多少天
		long days = diff / nd;
		// 计算差多少小时
		long hour = diff % nd / nh;
		// 计算差多少分钟
		long min = diff % nd % nh / nm;
		// 计算差多少秒//输出结果
		// long sec = diff % nd % nh % nm / ns;
		return min + hour * 60 + days * 24*60;
	}

	/**
	 * @param strDate
	 * @param dFormat
	 * @return
	 * @throws Throwable
	 */
	public static String dayForWeek(String strDate, String dFormat) {

		SimpleDateFormat format = new SimpleDateFormat(dFormat);

		Date tmpDate = null;
		try {
			tmpDate = format.parse(strDate);
		} catch (ParseException e) {
			e.printStackTrace();
			return "-1";
		}

		Calendar cal = Calendar.getInstance();

		String[] weekDays = {"7", "1", "2", "3", "4", "5", "6"};

		try {

			cal.setTime(tmpDate);

		} catch (Exception e) {

			e.printStackTrace();

		}

		int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。

		if (w < 0)

			w = 0;

		return weekDays[w];

	}


	/**
	 * 将 yyyyMMdd 转换为 yyyy-MM-dd
	 * @param str
	 * @return frmstr
	 */
	public static String getDateStrForm(String str) {
		try {
			//String str = "20200828";
			SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
			formatter.setLenient(false);
			Date newDate = formatter.parse(str);
			formatter = new SimpleDateFormat("yyyy-MM-dd");
			return formatter.format(newDate);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return str;
	}

	/**
	 * 將  yyyy-MM-dd 转换成  yyyyMMdd 格式字符串
	 * @param busDate
	 * @return
	 */
	public static String getBusDate(String busDate){

		if(null==busDate || busDate.isEmpty()){
			return busDate;
		}
		if(busDate.length()==8){
			return busDate;
		}
		String busDateForm = null;
		try {
			SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
			formatter.setLenient(false);
			Date newDate = formatter.parse(busDate);
			formatter = new SimpleDateFormat("yyyyMMdd");
			busDateForm = formatter.format(newDate);
			return busDateForm;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return busDate;

	}

	/**
	 * 將  yyyyMMdd 转换成  yyyy-MM-dd 格式字符串
	 * @param busDate
	 * @return
	 */
	public static String getNormalBusDate(String busDate){

		if(null==busDate || busDate.isEmpty()){
			return busDate;
		}
		if(busDate.length()==10){
			return busDate;
		}
		String busDateForm = null;
		try {
			SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
			formatter.setLenient(false);
			Date newDate = formatter.parse(busDate);
			formatter = new SimpleDateFormat("yyyy-MM-dd");
			busDateForm = formatter.format(newDate);
			return busDateForm;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return busDate;

	}

	/**
	 * 获取指定一个日期对象
	 * @param busDate
	 * @return
	 */
	public static Date getDate(String busDate){
		busDate = getNormalBusDate(busDate);
		if(null==busDate || busDate.isEmpty()){
			return null;
		}
		try {
			DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
			return  dateFormat.parse(busDate);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 获取指定一个日期对象
	 * @param dateStr
	 * @param dfm
	 * @return
	 */
	public static Date getDate(String dateStr , String dfm){
		if(null==dateStr || dateStr.isEmpty()){
			return null;
		}
		try {
			DateFormat dateFormat = new SimpleDateFormat(dfm);
			return  dateFormat.parse(dateStr);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}

}
